#ifndef FRAMEQUEUE_H
#define FRAMEQUEUE_H

#include <list>
#include <mutex>
#include <memory>

extern "C"
{
#include <libavutil/frame.h>
}

#include <QSemaphore>
#include <QDateTime>

struct DecodecSerial {
    int64_t timepoint = 0;
    qint64 id = -1;

    DecodecSerial() {}

    DecodecSerial(int64_t s) : timepoint(s){
        id = QDateTime::currentMSecsSinceEpoch();
    }

    DecodecSerial(const DecodecSerial& r) :timepoint(r.timepoint), id(r.id) {};

    DecodecSerial& operator = (int64_t serial) {
        this->timepoint = serial;
        this->id = QDateTime::currentMSecsSinceEpoch();
        return *this;
    }

    bool operator == (const DecodecSerial& r) {
        return this->timepoint == r.timepoint && this->id == r.id && id != -1;
    }

    bool operator != (const DecodecSerial& r) {
        return !(*this == r);
    }
};

class FrameQueue
{
public:

    FrameQueue();

    ~FrameQueue();

    bool isEmpty();

    bool push(AVFrame* frame);

    AVFrame* pop(int timeout = 100);

    int size();

    void clear();

    DecodecSerial serial();

    void setSerial(const DecodecSerial& s);

protected:

    std::list<AVFrame*> m_q;
    std::mutex m_m;
    std::unique_ptr<QSemaphore> m_sema;
    DecodecSerial m_serial = 0;
    std::mutex m_serialMutex;
};

#endif // FRAMEQUEUE_H
